<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #calendar-pre {
        margin-right: 40px;
        cursor: pointer;
        transition: all .36s ease;
      }

      #calendar-pre:hover {
        font-size: 18px;
        margin-right: 30px;
        transition: all .36s ease;
      }

      #calendar-next {
        margin-left: 40px;
        cursor: pointer;
      }

      #calendar-next:hover {
        font-size: 18px;
        margin-left: 30px;
        transition: all .36s ease;
      }

      .calendar {
        width: 900px;
        height: 400px;
      }
      .calendar .title {
        height: 50px;
        background-color: lightgreen;
        display: flex;
        align-items: center;
        justify-content: space-between;
      }
      .calendar-table {
        width: 100%;
        text-align: center;
        border: 1px solid #000;
      }
      .curr-date {
        height: 100px;
        border: 1px solid blue;
        text-align: left;
      }
      .curr-date .curr-date__day {
        float: right;
        margin-right: 5px;
      }
      .last-date {
        color: #989898;
        background-color: #33333330;
      }
      .next-date {
        color: #989898;
        background-color: #33333330;
      }
      .menu {
        opacity: .2;
        visibility: hidden;
        position: absolute;
        top: 0;
        left: 0;
        width: 100px;
        text-align: center;
        background-color: #afafaf;
        transition: all .26s ease-in;
        cursor: pointer;
        height: 1px;
        overflow: hidden;
      }
      .menu p {
        border-bottom: 1px solid #333;
        margin: 0;
        padding: 10px 0;
      }
      .is-open {
        opacity: 1;
        visibility: visible;
        height: 84px;
        transition: opacity .36s ease-out;
        transition: height .36s ease-out;
      }
    </style>
  </head>
  <body>
    <div id="calendar" class="calendar"></div>
    <div class="menu">
      <p>删除</p>
      <p>编辑</p>
    </div>

    <script>
      var calBox = document.getElementById('calendar')
      const oMenu = document.getElementsByClassName('menu')[0]
      var str = `
        <div class='title'>
          <a id='calendar-pre'>&lt;上月（${preMonth}月）</a>
          <label> ${year} 年</label>
          <label> ${month} 月</label> 
          <a id='calendar-next'>下月(${nextMonth})&gt;</a>
        </div>
        <table class='calendar-table'>
        </table>
      `
      calBox.innerHTML = str

      var now = new Date() //当前日期
      var year = now.getFullYear() // 年份
      var month = now.getMonth() + 1 // 月份
      var preMonth = now.getMonth() // 上个月
      var nextMonth = month + 1 // 下个月
      var days, whatday, predays //days表示当月天数，predays表示上个月天数，whatday表示当月一号所在的是周几
      var weeks = ['一', '二', '三', '四', '五', '六', '日'] //设置头部是从周一开始还是周日开始
      var begin //传入参数，用于设置上一个月还剩几天的天数显示
      function setNewDate() {
        //设置日期的方法
        if (month == 1) {
          //当前月为1月时，上一个月显示为12月
          preMonth = 12
        }
        if (month == 12) {
          //当前月为12月时，下一个月显示为1月
          nextMonth = 1
        }
        now.setFullYear(year, month, 0)
        days = now.getDate() //当前月天数
        now.setDate(1) //获取的是1号
        whatday = now.getDay() // 获取1号在周几
        now.setFullYear(year, month - 1, 0)
        predays = now.getDate() // 上个月天数
        begin = predays - whatday + 2 // 设置上一个月还剩几天的天数显示
        getCalendar(weeks, begin, whatday - 1) //传入参数，调用getCalender方法
      }
      setNewDate() // 初始化日期

      function getCalendar(weeks, begin, whichday) {
        var calBox = document.getElementById('calendar') //获取日历的dom对象
        var str = `
        <div class='title'>
          <a id='calendar-pre'>&lt;上月（${preMonth}月）</a>
          <section>
            <label>${year}年</label>
            <label>${month}月</label>
          </section>
          <a id='calendar-next'>下月(${nextMonth})月）&gt;</a>
        </div>
        <table class='calendar-table'>
          <tr>
        `
        for (var i = 0; i < 7; i++) {
          //渲染头部
          str += '<th>' + weeks[i] + '</th>'
        }
        str += '</tr>'
        var line = Math.ceil((days + whichday) / 7) + 1 // 行数
        var curIndex = 1 //当前天
        var start = begin //上一个月遗留的天数显示
        var flag = false //这个月的天数是否渲染完成
        for (var l = 0; l < line; l++) {
          str += '<tr>'
          for (var i = 0; i < 7; i++) {
            //一周七天
            if (i < whichday && l == 0) {
              //当i小于一号所在的周几数就表示上个月还剩余天数未渲染
              str += `<td class="last-date">${start}</td>` //渲染上个月的剩余天数，并置为灰色
              start++
            } else if (curIndex > days || flag == true) {
              //当月天数渲染完之后，剩余的位置用于渲染下个月的天数
              flag == true
              str += `<td class='next-date'>${(curIndex - days)}</td>`
              curIndex++
            } else {
              //渲染当月的天数
              str += `<td>
                <section class="curr-date" data-dateNum="${curIndex}">
                  <span class="curr-date__day">${curIndex}</span>
                  <p>值班人：XXX</p></p>
                </section>
              </td>`
              curIndex++
            }
          }
          str += '</tr>'
        }
        str += '</table>'
        calBox.innerHTML = str
      }

      setNewDate() // 初始化日期

      calendar.addEventListener('click', function (e) {
        //为两个按钮设置事件委托
        const target = e.target
        console.log(target)
        changeMenu('close')

        if (e.target.id == 'calendar-pre') {
          //当点击上一个月的按钮时
          month = preMonth
          preMonth = month - 1
          nextMonth = month + 1
          if (month == 12) {
            //边界值判断
            year--
          }
          setNewDate() //更新日期
        }
        if (e.target.id == 'calendar-next') {
          //当点击下一个月的按钮时
          month = nextMonth
          preMonth = month - 1
          nextMonth = month + 1
          if (month == 1) {
            //边界值判断
            year++
          }
          setNewDate() //更新日期
        }
      })

      calendar.addEventListener('contextmenu', function (event) {
        var event = event || window.event
        const target = event.target || event.srcElement
        const num = target.dataset.datenum
        event.preventDefault();
        console.log('right', event, target, num)
        if(num) {
          changeMenu('open')
          oMenu.style.top = event.clientY + 'px'
          oMenu.style.left = event.clientX + 'px'
        } else {
          changeMenu('close')
        }
      })

      const changeMenu = (type) => {
        oMenu.className = type === 'open' ? 'menu is-open' : 'menu'
      }

      const domS = []
      const moveHandle = (event) => {
        var event = event || window.event
          const target = event.target || event.srcElement
          const num = target.dataset.datenum
          if(!num) {
            return
          }
          domS.indexOf(num) === -1 && domS.push(num)
          console.log('move', domS)
      }
      calendar.addEventListener('mousedown', function (event) {
        console.log('d', event)
        calendar.addEventListener('mousemove', moveHandle, false)
      })

      calendar.addEventListener('mouseup', function (event) {
        console.log('up', event)
        // alert('选择日期' + domS.toString())
        calendar.removeEventListener('mousemove', moveHandle, false)
      })

      calendar.addEventListener('dblclick', function (event) {
        var event = event || window.event
          const target = event.target || event.srcElement
          const num = target.dataset.datenum
          const idx = domS.indexOf(num)
          idx === -1 ? domS.push(num) : domS.splice(idx, 1)
          console.log(domS)
      })
    </script>
  </body>
</html>
